//   Copyright 2009
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package com.navjagpal.notes;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;

public class NotesProvider extends ContentProvider {
  
  private class DatabaseOpenHelper extends SQLiteOpenHelper {

    public DatabaseOpenHelper(
        Context context, String name, CursorFactory factory, int version) {
      super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
      database.execSQL(
          "CREATE TABLE LIST" +
          "(_id INTEGER PRIMARY KEY AUTOINCREMENT, name STRING,"+
          "last_modified INTEGER," +
          "last_sync INTEGER DEFAULT 0," +
          "list_url TEXT," +
          "post_url TEXT)");
      database.execSQL(
          "CREATE TABLE NOTE" +
          "(_id INTEGER PRIMARY KEY AUTOINCREMENT, title STRING," +
          "contents STRING, list_id INTEGER, last_modified INTEGER," +
          "last_sync INTEGER DEFAULT 0," +
          "edit_url TEXT UNIQUE," +
          "gdata_id TEXT)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
      // TODO Auto-generated method stub
      
    }   
  }
  
  public interface List {
    public static final Uri CONTENT_URI = 
      Uri.parse("content://com.navjagpal.notes.notesprovider/list");
    public static final String CONTENT_TYPE = 
      "vnd.android.cursor.dir/vnd.navjagpal.list";
    public static final String CONTENT_ITEM_TYPE = 
      "vnd.android.cursor.item/vnd.navjagpal.list";
    
    public interface Columns extends BaseColumns {
      public static final String NAME = "name";
      public static final String LAST_MODIFIED = "last_modified";
      public static final String POST_URL = "post_url";
      public static final String LIST_URL = "list_url";
      public static final String LAST_SYNC = "last_sync";
    }
  }
  
  public interface Note {
    public static final Uri CONTENT_URI =
      Uri.parse("content://com.navjagpal.notes.notesprovider/note");
    public static final String CONTENT_TYPE = 
      "vnd.android.cursor.dir/vnd.navjagpal.note";
    public static final String CONTENT_ITEM_TYPE = 
      "vnd.android.cursor.item/vnd.navjagpal.note";
    
    public interface Columns extends BaseColumns {
      public static final String LIST_ID = "list_id";
      public static final String TITLE = "title";
      public static final String CONTENTS = "contents";
      public static final String LAST_MODIFIED = "last_modified";
      public static final String LAST_SYNC = "last_sync";
      public static final String EDIT_URL = "edit_url";
      public static final String GDATA_ID = "gdata_id";
    }
  }

  private static UriMatcher sUriMatcher;
  private static final int LISTS = 0;
  private static final int LIST = 1;
  private static final int NOTES = 2;
  private static final int NOTE = 3;
  private SQLiteDatabase database;
  private String TABLE_LIST = "LIST";
  private String TABLE_NOTE = "NOTE";
  
 
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    switch (sUriMatcher.match(uri)) {
      case NOTES:
        return database.delete(TABLE_NOTE, selection, selectionArgs);
      case LISTS:
        return database.delete(TABLE_LIST, selection, selectionArgs);
    }
    return 0;
  }

  @Override
  public String getType(Uri uri) {
    switch (sUriMatcher.match(uri)) {
      case LISTS:
        return List.CONTENT_TYPE;
      case LIST:
        return List.CONTENT_ITEM_TYPE;
      case NOTES:
        return Note.CONTENT_TYPE;
      case NOTE:
        return Note.CONTENT_ITEM_TYPE;
      default:
        Log.i("Note", "Type is unknown");
        throw new IllegalArgumentException("Unknown URI " + uri);
    }
  }

  @Override
  public Uri insert(Uri uri, ContentValues values) {
    switch (sUriMatcher.match(uri)) {
      case LISTS:
        if (!values.containsKey(List.Columns.NAME)) {
          throw new IllegalArgumentException("Name required");
        }
        long listId = database.insert(TABLE_LIST, List.Columns.NAME, values);
        if (listId != -1) {
          // TODO(nav): This notify doesn't seem to work.
          getContext().getContentResolver().notifyChange(uri, null);
          return ContentUris.withAppendedId(List.CONTENT_URI, listId);
        }
        break;
      case NOTES:
        if (!values.containsKey(Note.Columns.TITLE)) {
          throw new IllegalArgumentException("Title required");
        }
        long noteId = database.insert(TABLE_NOTE, Note.Columns.TITLE, values);
        if (noteId != -1) {
          // TODO(nav): This notify doesn't seem to work.
          getContext().getContentResolver().notifyChange(uri, null);
          return ContentUris.withAppendedId(Note.CONTENT_URI, noteId);
        }
        break;
    }      
    return null;
  }

  @Override
  public boolean onCreate() {
    SQLiteOpenHelper helper = new DatabaseOpenHelper(
        getContext(), TABLE_LIST, null, 1);
    database = helper.getWritableDatabase();
    // TODO(nav): What should the return value be?
    return true;
  }

  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
      String[] selectionArgs, String sortOrder) {
    switch (sUriMatcher.match(uri)) {
      case LISTS:
        return database.query(TABLE_LIST, projection, selection, selectionArgs,
            null, null, sortOrder);
      case NOTES:
        return database.query(TABLE_NOTE, projection, selection, selectionArgs,
            null, null, sortOrder);
    }
    return null;
  }

  @Override
  public int update(Uri uri, ContentValues values, String selection,
      String[] selectionArgs) {
    switch (sUriMatcher.match(uri)) {
      case NOTES:
        return database.update(TABLE_NOTE, values, selection, selectionArgs);
    }
    return 0;
  }
   
  static {
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    sUriMatcher.addURI("com.navjagpal.notes.notesprovider", "list", LISTS);
    sUriMatcher.addURI("com.navjagpal.notes.notesprovider", "list/#", LIST);
    sUriMatcher.addURI("com.navjagpal.notes.notesprovider", "note", NOTES);
  }

}
